home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-09-29 | 3.2 KB | 167 lines | [TEXT/Rich] |
- { components for billiard simulation }
- { written by Tim Budd, Oregon State University }
- { April 1990 }
-
- unit billiardComponents;
- interface
- uses
- graphicUniverse;
-
- type
-
- wall = object(GraphicalObject)
- convertFactor: real;
- procedure setBounds (left, top, right, bottom: integer; cf: real);
- procedure draw; override;
- procedure hitBy (anObject: GraphicalObject); override;
- end;
-
- hole = object(GraphicalObject)
- procedure setCenter (x, y: integer);
- procedure draw; override;
- procedure hitBy (anObject: GraphicalObject); override;
- end;
-
- ball = object(hole)
- direction: real;
- energy: real;
- procedure draw; override;
- procedure update; override;
- procedure hitBy (anObject: GraphicalObject); override;
- function x: real;
- function y: real;
- end;
-
- var
- theUniverse: ObjectUniverse;
- cueBall: ball;
- saveRack: integer;
-
- function hitAngle (dx, dy: real): real;
-
- implementation
-
- function hitAngle (dx, dy: real): real;
- const
- PI = 3.14159;
- var
- na: real;
- begin
- if (abs(dx) < 0.05) then
- na := PI / 2
- else
- na := arctan(abs(dy / dx));
- if (dx < 0) then
- na := PI - na;
- if (dy < 0) then
- na := -na;
- hitAngle := na;
- end;
-
- procedure wall.setBounds (left, top, right, bottom: integer; cf: real);
- begin
- convertFactor := cf;
- SetRect(region, left, top, right, bottom);
- end;
-
- procedure wall.draw;
- begin
- PaintRect(region);
- end;
-
- procedure wall.hitBy (anObject: GraphicalObject);
- var
- theBall: ball;
- begin
- theBall := ball(anObject);
- theBall.direction := convertFactor - theBall.direction;
- theUniverse.continueSimulation;
- draw;
- end;
-
- procedure hole.setCenter (x, y: integer);
- begin
- SetRect(region, x - 5, y - 5, x + 5, y + 5);
- end;
-
- procedure hole.draw;
- begin
- PaintOval(region);
- end;
-
- procedure hole.hitBy (anObject: GraphicalObject);
- var
- theBall: ball;
- begin
- theBall := ball(anObject);
- if (theBall = cueBall) then
- theBall.setCenter(50, 100)
- else
- begin
- saveRack := saveRack + 1;
- theBall.setCenter(10 + saveRack * 15, 250);
- end;
- theBall.energy := 0.0;
- anObject.draw;
- end;
-
- function ball.x: real;
- begin
- x := (region.left + region.right) / 2;
- end;
-
- function ball.y: real;
- begin
- y := (region.top + region.bottom) / 2;
- end;
-
-
- procedure ball.draw;
- begin
- if (self = cueBall) then
- FrameOval(region)
- else
- PaintOval(region);
- end;
-
- procedure ball.update;
- var
- hit: GraphicalObject;
- dx, dy: integer;
- i, xdir, ydir, ymove: integer;
- begin
- if (energy > 0.5) then
- begin
- erase;
- energy := energy - 0.05;
- if energy > 0.5 then
- theUniverse.continueSimulation;
- dx := trunc(5.0 * cos(direction));
- dy := trunc(5.0 * sin(direction));
- offsetRect(region, dx, dy);
- hit := theUniverse.hitObject(self);
- if hit <> nil then
- begin
- hit.hitBy(self);
- theUniverse.draw;
- end
- else
- draw;
- end;
- end;
-
- procedure ball.hitBy (anObject: GraphicalObject);
- var
- aBall: ball;
- da: real;
- begin
- aBall := ball(anObject);
- energy := aBall.energy / 2;
- aBall.energy := energy;
- direction := hitAngle(self.x - aBall.x, self.y - aBall.y);
- da := aBall.direction - direction;
- aBall.direction := aBall.direction + da;
- theUniverse.continueSimulation;
- end;
- end.
-